/*
 * User: rant
 * Date: Aug 13, 2007
 *
 *
 */
package laMalinche.testingPlayGround.swingTest;

import laMalinche.BasicConstraintLaMa;
import laMalinche.LaMalinche;
import laMalinche.LaMaContext;
import laMalinche.constraint.ConstraintResult;
import laMalinche.constraint.ConstraintRuleListener;
import laMalinche.propertyChangeAdapters.model.AccessReporterImp;
import laMalinche.rete.rule.ProductionRule;
import laMalinche.testingPlayGround.testModel.PersonVo;
import laMalinche.testingPlayGround.flow.FlowHolder;
import laMalinche.testingPlayGround.flow.BasicFlowNode;
import laMalinche.testingPlayGround.flow.Collector;
import laMalinche.testingPlayGround.flow.Navigator;

import javax.swing.*;
import java.awt.*;
import static java.awt.Component.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.util.*;

/**
 *
 */
public class EditorFlow implements ActionListener, ConstraintRuleListener {
    private LaMalinche laMalinche;
    private PersonVo person;
    private AccessReporterImp accessReporterImp;
    private JFrame frame;
    private PropertyEditor propertyEditor;
    private ConstraintResult constraintResult;
    private SwingFlow swingFlow;
    private PersonVo flowPerson;

    public static void main(String[] args) {
        final EditorFlow editorFlow = new EditorFlow();
        editorFlow.initializeLaMa();
        editorFlow.initializeFlow();
        editorFlow.initializeGuy();
    }

    private FlowHolder initializeFlow() {
        BasicFlowNode node = new BasicFlowNode(new Collector(person,"age"));
        node.addNavigator(new Navigator(){
            public Collector navigate(Collector collector) {
                PersonVo vo;
                if (person.getAge()>5) {
                     vo = person.getFather();//To change body of implemented methods use File | Settings | File Templates.
                }  else {
                    vo = person.getMother();

                }
                return new Collector(vo, "age");
            }
        });
         return new FlowHolder(node);

    }


    public void initializeGuy() {
        frame = new JFrame("flow");
        frame.getContentPane().setLayout(new GridLayout());
        populateFlow();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void initializeLaMa() {
        accessReporterImp = new AccessReporterImp();
        makeModel(accessReporterImp);
        swingFlow = new SwingFlow(person);

        makeLaMa();
        laMalinche.start();
    }

    protected LaMalinche makeLaMa() {
        laMalinche = new BasicConstraintLaMa();
        LaMaContext.getInstance().setAccessReporter(accessReporterImp);
        laMalinche.setAboutToChangeManager(swingFlow.getAboutToChangeManager());
        laMalinche.add(SwingTestRules.createteProductionRules(person));
        LaMaContext.getInstance().setAccessReporter(accessReporterImp);
        laMalinche.setConstraintRuleListener(this);
        return laMalinche;
    }


    protected PersonVo makeModel(PropertyChangeListener propertyChangeListener) {
        person = new PersonVo();
        person.setAge(5);
        person.setAccessReporter(propertyChangeListener);
        final PersonVo mother = new PersonVo();
        mother.setAge(2);
        person.setMother(mother);
        final PersonVo father = new PersonVo();
        person.setFather(father);
        father.setAge(3);
        return person;
    }

    public void actionPerformed(ActionEvent e) {
        final int i = propertyEditor.getValue();
        flowPerson.setAge(i);
        laMalinche.updateConstraintStatus();
        if (!constraintResult.getInvalidConstraints().isEmpty()) {
            JOptionPane.showMessageDialog(frame, getConstraintString());
        } else {
            populateFlow();
        }
    }

    String getConstraintString() {
        final Set<ProductionRule> constraints = constraintResult.getInvalidConstraints();
        StringBuffer buf = new StringBuffer();
        for (ProductionRule rule : constraints) {
            buf.append("there is a constraint you passed: ");
            buf.append(rule.getName() + "\n");
        }
        return buf.toString();
    }


    private void populateFlow() {
        flowPerson = swingFlow.getNext();
        if (flowPerson == null) {
            endOfFlow();
            return;
        }
        propertyEditor = new PropertyEditor(flowPerson, "Age");
        frame.getContentPane().removeAll();
//		frame.getContentPane().add(propertyEditor);
        final Button button = new Button("next");
        button.addActionListener(this);
//		frame.getContentPane().add(button);
        JPanel panel = new JPanel();
        panel.setAlignmentX(LEFT_ALIGNMENT);
        panel.setLayout(new FlowLayout(FlowLayout.LEFT));
        panel.add(propertyEditor);
        panel.add(button);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    private void endOfFlow() {

        // todo
        frame.getContentPane().removeAll();
        frame.getContentPane().add(new JLabel("this was the last"));
        frame.pack();
        frame.setVisible(true);

    }

    public void constraintViolated(Object validationResult) {
        constraintResult = ((ConstraintResult) validationResult);
    }
}